package com.mazaiting.auth.security.extension.refresh;

import com.mazaiting.auth.enums.AuthenticationIdentityEnum;
import com.mazaiting.auth.enums.RefreshTypeEnum;
import com.mazaiting.auth.security.core.userdetails.member.MemberUserDetailsServiceImpl;
import com.mazaiting.auth.security.core.userdetails.user.SysUserDetailsServiceImpl;
import com.mazaiting.auth.utils.RequestUtil;
import com.mazaiting.common.core.domain.result.ResultCode;
import com.mazaiting.common.core.enums.IBaseEnum;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.util.Map;

/**
 * 刷新token再次认证 UserDetailsService
 */
@Slf4j
@NoArgsConstructor
public class PreAuthenticatedUserDetailsService<T extends Authentication> implements AuthenticationUserDetailsService<T>, InitializingBean {

    /**
     * 客户端ID和用户服务 UserDetailService 的映射
     *
     * @see com.mazaiting.auth.security.config.AuthorizationServerConfig#tokenServices(AuthorizationServerEndpointsConfigurer)
     */
    private Map<String, UserDetailsService> userDetailsServiceMap;

    public PreAuthenticatedUserDetailsService(Map<String, UserDetailsService> userDetailsServiceMap) {
        Assert.notNull(userDetailsServiceMap, "userDetailsService cannot be null.");
        this.userDetailsServiceMap = userDetailsServiceMap;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Assert.notNull(this.userDetailsServiceMap, "UserDetailsService must be set");
    }

    /**
     * 重写PreAuthenticatedAuthenticationProvider 的 preAuthenticatedUserDetailsService 属性，可根据客户端和认证方式选择用户服务 UserDetailService 获取用户信息 UserDetail
     *
     * @param authentication 认证对象
     */
    @Override
    public UserDetails loadUserDetails(T authentication) throws UsernameNotFoundException {
        try {
            // 获取刷新类型
            RefreshTypeEnum refreshTypeEnum = StringUtils.hasLength(RequestUtil.getRefreshType())
                    ? IBaseEnum.getEnumByValue(RequestUtil.getRefreshType(), RefreshTypeEnum.class)
                    : RefreshTypeEnum.CLIENT_MANAGER;
            // 获取认证身份标识，默认是用户名:username
            AuthenticationIdentityEnum authenticationIdentityEnum =
                    StringUtils.hasLength(RequestUtil.getAuthenticationIdentity())
                            ? IBaseEnum.getEnumByValue(RequestUtil.getAuthenticationIdentity(), AuthenticationIdentityEnum.class)
                            : AuthenticationIdentityEnum.USERNAME;
            UserDetailsService userDetailsService = userDetailsServiceMap.get(refreshTypeEnum.name());
            // 根据刷新类型选择
            // 后管
            if (refreshTypeEnum == RefreshTypeEnum.CLIENT_MANAGER) {
                // 强转
                SysUserDetailsServiceImpl sysUserDetailsService = (SysUserDetailsServiceImpl) userDetailsService;
                // 认证类型
                if (authenticationIdentityEnum == AuthenticationIdentityEnum.MOBILE) {
                    return sysUserDetailsService.loadUserByMobile(authentication.getName());
                }
                return sysUserDetailsService.loadUserByUsername(authentication.getName());
            } else {
                // 强转
                MemberUserDetailsServiceImpl memberUserDetailsService = (MemberUserDetailsServiceImpl) userDetailsService;
                // 认证类型
                if (authenticationIdentityEnum == AuthenticationIdentityEnum.OPENID) {
                    return memberUserDetailsService.loadUserByOpenId(authentication.getName());
                }
                return userDetailsService.loadUserByUsername(authentication.getName());
            }

//        if (clientId.equals(SecurityConstants.APP_CLIENT_ID)) {
//            // 移动端的用户体系是会员，认证方式是通过手机号 mobile 认证
//            MemberUserDetailsServiceImpl memberUserDetailsService = (MemberUserDetailsServiceImpl) userDetailsService;
//            switch (authenticationIdentityEnum) {
//                case MOBILE:
//                    return memberUserDetailsService.loadUserByMobile(authentication.getName());
//                default:
//                    return memberUserDetailsService.loadUserByUsername(authentication.getName());
//            }
//        } else if (clientId.equals(SecurityConstants.WEAPP_CLIENT_ID)) {
//            // 小程序的用户体系是会员，认证方式是通过微信三方标识 openid 认证
//            MemberUserDetailsServiceImpl memberUserDetailsService = (MemberUserDetailsServiceImpl) userDetailsService;
//            switch (authenticationIdentityEnum) {
//                case OPENID:
//                    return memberUserDetailsService.loadUserByOpenId(authentication.getName());
//                default:
//                    return memberUserDetailsService.loadUserByUsername(authentication.getName());
//            }
//        } else
//            if (clientId.equals(SecurityConst.ADMIN_CLIENT_ID)) {
//                // 管理系统的用户体系是系统用户，认证方式通过用户名 username 认证
//                return userDetailsService.loadUserByUsername(authentication.getName());
//            } else {
//                return userDetailsService.loadUserByUsername(authentication.getName());
//            }
        } catch (Exception e) {
            log.error("获取用户详细信息失败: " + e.getMessage());
            throw new UsernameNotFoundException(ResultCode.ACCESS_UNAUTHORIZED.getMessage());
        }
    }
}
